<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>接口测试</title>
</head>
<style type="text/css">
    *{
        margin: 0;
        padding: 0;
    }
    html,body{
        min-width: 800px;
        min-height: 600px;
        height: 100%;
        width: 100%;
        overflow: hidden;
        font-size: 14px;
    }
    div{
        display: block;
    }
    input[type="text"]{
        height: 30px;
        border: 1px solid #ccc;
        padding: 0 14px;
        border-radius: 6px;
        width: 200px;
    }
    button, input[type="button"]{
        height: 32px;
        border: 1px solid #ccc;
        padding: 0 14px;
        border-radius: 6px;
        text-align: center;
        background-color: #248bfc;
        color: #ffffff;
        cursor: pointer;
    }
    div#top{
        height: 5%;
        border-bottom: #eeeeee solid 1px;
    }
    div#left{
        min-width: 200px;
        width: 40%;
        float: left;
        height: 40%;
        border-right: #eeeeee solid 1px;
        padding: 5px 0px 0px 5px;
    }
    div#left ul{
        text-underline: none;
    }
    div#left ul li{

    }
    div#left ul li:hover{
        background-color: bisque;
    }
    div#left div#search_result{
        overflow: auto;
        height: 90%;
    }
    div#right{
        width: 59%;
        margin-left: 40%;
        height: 40%;
        /*position: relative;*/
        z-index: 0;
        padding: 5px 0px 0px 10px;
    }
    div#right span{
        display: inline-block;
        line-height: 28px;
        /*vertical-align: top;*/
    }
    div.job_cmd_param{
        height: 40px;
    }
    div.job_cmd_param span{
        width: 180px;
        margin-right: 20px;
        margin-left: 5px;
    }
    div.job_cmd_param input{
        width: 200px;
    }
    div#bottom{
        border-top: #eeeeee solid 1px;
        padding: 0;
        height: 50%;
        z-index: 99;
        overflow-y: scroll;
        background-color: #555555;
        color: #ffffff;
    }
    div.output{

    }
    div#floor{
        position: fixed;
        left: 0;
        bottom: 0;
    }
    span.redo{
        cursor: pointer;
        color: #248bfc;
    }
</style>
<body>
<div style="height: 100%;width: 100%;display: block;padding:0;">
    <div id="top">

    </div>
    <div id="left">
        <div>
            <input type="text" name="code" id="code" placeholder="输入请求CODE">
            <input type="button" value="查看" id="codeSearch">
        </div>
        <div id="search_result">
            <ul>
            </ul>
        </div>
    </div>
    <div id="right">
        <div>
            <input type="text" name="user" id="user" placeholder="输入玩家ID"/>
            <input type="button" value="登录" id="createJob"/>
            <input type="button" value="登出" id="delJob"/>
            <input type="button" value="执行CODE" id="calJob"/>
            <input type="button" value="暂停" id="pauseJob"/>
            <input type="button" value="刷新" id="getJob"/>
            <div style="display: inline-block;">
                <input type="checkbox" id="_loop"/>
                <span>循环</span>
            </div>
        </div>
        <div id="allSelect" style="vertical-align: center;border-bottom: #eeeeee solid 1px">
            <input type="checkbox" value="全选" title="全选"><span>全选</span>
        </div>
        <div id="jobPanel" style="z-index:-1;overflow-y: scroll;height: 78%; border: none;">
            <!--                <div class="job">-->
            <!--                    <div>-->
            <!--                        <input type="checkbox"><span>job1</span>-->
            <!--                    </div>-->
            <!--                    <div class="job_cmd_param">-->
            <!--                        <span>code</span><input/>-->
            <!--                    </div>-->
            <!--                    <div class="job_cmd_param">-->
            <!--                        <span>activityId</span><input/>-->
            <!--                    </div>-->
            <!--                    <div class="job_cmd_param">-->
            <!--                        <span>userId</span><input/>-->
            <!--                    </div>-->
            <!--                </div>-->
        </div>
    </div>
    <div id="bottom">
        <div class="output">
            输出
        </div>
        <!--            <div class="output">-->
        <!--                输出-->
        <!--            </div>-->
    </div>
</div>
<div id="floor">
    <div>
        <input type="button" value="清空" id="clearOutput"/>
    </div>
</div>
</body>
<script type="text/javascript">
    (function(params) {

        let resultReq = 1;
        let timer = params.setInterval(getResult, 2000);

        params.onunload = function (){
            console.log("释放定时器");
            params.clearInterval(timer);
        };

        function getResult(){
            for (let i = 0; i < jobData.length; i++) {
                let job = jobData[i];
                sendGetRequest("job/jobResult/" + job["jobId"], null, null, function (result){
                    let temp = JSON.parse(result);
                    let jobId = temp["jobId"];
                    let array = temp["result"];
                    if(array){
                        for (let j = 0; j < array.length; j++) {
                            let content = JSON.stringify(array[j]);
                            console.log("jobId:" + jobId + ", result : " + content);
                            outPutConsole(jobId, content, true);
                        }
                    }
                });
            }

            //console.log("请求结果：" + resultReq++);
        }

        //请求接口元数据
        let codeMap = [];
        sendGetRequest("api/list", null, null, function(result){
            try{
                codeMap = JSON.parse(result);
                codeMap.sort(function (a, b){ return a.code - b.code});
            }catch (e){
                console.log(e);
                return;
            }
            renderCodeMetaInfo(codeMap);
            console.log(result);
        });

        function renderCodeMetaInfo(codeMap){
            let divDom = document.getElementById("search_result");
            let ulDom = divDom.children[0];
            ulDom.innerHTML = "";
            for (let i = 0; i < codeMap.length; i++) {
                let obj = codeMap[i];
                let liDom = document.createElement("li");
                liDom.setAttribute("code", obj["code"]);
                liDom.innerText = "[" + obj["code"] + "]"+ obj["name"];
                ulDom.appendChild(liDom);
            }
        }

        let jobData = [];

        function addJobData(job){
            let newJob = true;
            for (let i = 0; i < jobData.length; i++) {
                let obj = jobData[i];
                if(job["jobId"] == obj["jobId"]){
                    newJob = false;
                    break;
                }
            }
            if(newJob){
                jobData.push(job);
            }
        }

        function getJobUserId(jobId){
            for (let i = 0; i < jobData.length; i++) {
                let obj = jobData[i];
                if (jobId == obj["jobId"]) {
                    return obj["userId"];
                }
            }
            return 0;
        }

        //请求当前job
        function listJob(){
            sendGetRequest("job/list", null, null, function (result){
                try{
                    jobData = JSON.parse(result);
                    jobData.sort(function (a, b){ return a["jobId"] - b["jobId"]});
                }catch (e){
                    console.log(e);
                    return;
                }
                jobPanelDom.innerHTML = "";
                if(jobData.length > 0){
                    for (let i = 0; i < jobData.length; i++) {
                        let job = jobData[i];
                        renderJobDiv(job["jobId"], job["userId"]);
                    }
                }
            });
        }

        //创建job
        function createJob(){
            let userId = document.getElementById("user").value;
            if(userId.length <= 0){
                alert("请求输入玩家id");
                document.getElementById("user").focus();
                return;
            }
            let url = "job/newJob/" + userId;
            sendPostRequest(url, null, null, function (result){
                let json = JSON.parse(result);
                console.log("new Job(id:" + json["jobId"] + ",userId:" + json["userId"] +")");
                if(json["jobId"]){
                    renderJobDiv(json["jobId"], userId);
                    addJobData(json);
                }
            });
        }

        //删除job
        function delJob(){
            let chkArr = getCheckSelect();
            let param = [];
            for (let i = 0; i < chkArr.length; i++) {
                let dom = chkArr[i];
                let jobId = dom.getAttribute("attr_jobId");
                param.push(jobId);
            }
            if(param.length > 0){
                sendPostRequest("job/del", "jobId=" + param.join(","), null, function (result){
                    console.log("del result : " + result);
                    listJob();
                });
            }
        }


        //停止执行cmd
        function pause(){
            let chkArr = getCheckSelect();
            let param = [];
            for (let i = 0; i < chkArr.length; i++) {
                let dom = chkArr[i];
                let jobId = dom.getAttribute("attr_jobId");
                param.push(jobId);
            }
            if(param.length > 0){
                sendPostRequest("job/pause", "jobId=" + param.join(","), null, function (result){
                    console.log("pause result : " + result)
                    //listJob();
                });
            }
        }

        //执行方法
        function callCMD(){
            let chkArr = getCheckSelect();
            let param = [];
            for (let i = 0; i < chkArr.length; i++) {
                let dom = chkArr[i];
                let obj = {};
                let userId = dom.getAttribute("attr_userId");
                let code = dom.children[1].getAttribute("attr_code");
                obj["userId"] = userId;
                obj["code"] = code;
                obj["params"] = {};
                let send = false;
                for (let j = 0; j < dom.children[1].children.length; j++) {
                    let paramDom = dom.children[1].children[j];
                    if(paramDom.children.length <= 1){
                        continue;
                    }
                    let repeated = false;
                    if(paramDom.hasAttribute("repeated")){
                        repeated = true;
                    }
                    let p = paramDom.children[0].textContent;
                    let v = paramDom.children[1].value;
                    obj["params"][p] = v;
                    if(repeated){
                        obj["params"][p] = v.split(",");
                    }
                    send = true;
                }
                if(send){
                    param.push(obj);
                }else {
                    //是否无参数
                    let meta = findCode(code, codeMap);
                    if(meta.reqParamList.length == 0){
                        param.push(obj);
                    }
                }
            }
            let loop = document.getElementById("_loop").checked;
            if(param.length > 0){
                let postBody = JSON.stringify(param);
                //console.log("postBody:" + postBody);
                let url = "job/call?";
                if(loop){
                    url += "loop=loop";
                }
                sendCmdCall(url, postBody);
            }
        }

        function sendCmdCall(url, postBody){
            sendJOSONPostRequest(url, postBody, function (param){
                console.log(param);
                let result = JSON.parse(param);
                if(result.ret){
                    for (let i = 0; i < result["jobId"].length; i++) {
                        //console.log("jobId " + result["jobId"][i] + " call success");
                        outPutConsole(result["jobId"][i], postBody, false);
                    }
                }
            });
        }

        //循环打印调用结果
        let outPutDom = document.querySelector("div#bottom");
        function outPutConsole(jobId, content, out){
            let divDom = document.createElement("div");
            divDom.classList.add("output");
            divDom.setAttribute("attr_id", jobId);
            let text = " [jobId:" + jobId + "] [userId:" + getJobUserId(jobId) + "] [" + content + "]";
            text = " [" + new Date().format("yyyy-MM-dd HH:mm:ss") + "]"  + text;
            if(out){
                text = "[o]" + text;
            }else {
                text = "<span class='redo'>-></span>" + text;
            }
            divDom.innerHTML = text;
            outPutDom.appendChild(divDom);
            outPutDom.scrollTop = outPutDom.scrollHeight;
        }

        outPutDom.addEventListener("dblclick", function (event) {
            if (event.target.tagName === "span" || event.target.tagName === "SPAN") {
                if(event.target.classList.contains("redo")){
                    let content = event.target.parentElement.textContent;
                    let array = content.match(/(\[.+?\])/g);
                    let param = array[3];
                    console.log(param);
                    if(param){
                        let url = "job/call?";
                        sendCmdCall(url, param.substring(1, param.length));
                    }
                }
                event.stopImmediatePropagation()
                event.stopPropagation();
            }
        });

        //注册搜索事件
        document.getElementById("codeSearch").onclick = function (){
            let value = document.getElementById("code").value;
            if(value && value.length > 0){
                let result = [];
                for (let i = 0; i < codeMap.length; i++) {
                    let obj = codeMap[i];
                    let code = "" + obj["code"];
                    let desc = obj["name"];
                    if(code.indexOf(value) != -1 || desc.indexOf(value) != -1){
                        result.push(obj);
                    }
                }
                renderCodeMetaInfo(result);
            }else {
                renderCodeMetaInfo(codeMap);
            }
        }
        let divDom = document.getElementById("search_result");
        let ulDom = divDom.children[0];
        ulDom.addEventListener("dblclick", function (event){
            if(event.target.tagName === "LI" || event.target.tagName === "li"){
                let code = event.target.getAttribute("code")
                let meta = findCode(code, codeMap);
                if(meta){
                    renderSelect(meta);
                }
            }
            event.stopImmediatePropagation();
            event.stopPropagation();
            console.log(arguments.length);
        });

        function getCheckSelect() {
            let chkArr = [];
            for (let i = 0; i < jobPanelDom.children.length; i++) {
                let jobDom = jobPanelDom.children[i];
                let input = jobDom.children[0].children[0];
                if (input.checked) {
                    chkArr.push(jobDom);
                }
            }
            return chkArr;
        }

        //渲染job对参数
        function renderSelect(meta){
            let chkArr = getCheckSelect();
            for (let i = 0; i < chkArr.length; i++) {
                let cmdParamDom = createParam(meta, chkArr[i].children[1]);
                chkArr[i].children[1].innerHTML = cmdParamDom;
                chkArr[i].children[1].setAttribute("attr_code", meta.code);
            }
        }

        function createParam(meta, dom){
            let html = "";
            for (let i = 0; i < meta.reqParamList.length; i++) {
                let obj = meta.reqParamList[i];
                let repeated = obj.repeated ? "repeated" : "";
                html += "<div class='job_cmd_param' " + repeated + ">";
                html += "<span>" + obj.fieldName + "</span><input type='text'/>";
                html += "<span>" + obj.type + "</span>";
                html += "</div>"
            }
            if(html === ""){
                html += "<div class='job_cmd_param'><span>无需参数【code："+ meta["code"] +"】</span></div>";
            }
            console.log(meta);
            return html;
        }

        function renderJobDiv(jobId, userId){
            let div = document.createElement("DIV");
            div.setAttribute("id", "jobId_" + jobId);
            div.setAttribute("attr_jobId", jobId);
            div.setAttribute("attr_userId", userId);

            let firstChild = document.createElement("DIV");
            let chk = document.createElement("INPUT");
            chk.setAttribute("type", "checkbox");

            let span = document.createElement("SPAN");
            span.innerText = "玩家 - " + userId;

            firstChild.append(chk);
            firstChild.append(span);

            div.append(firstChild);
            div.append(document.createElement("DIV"));

            jobPanelDom.append(div);
        }

        function toInt(val){
            let v = 0;
            try{
                v = parseInt(val);
            }catch (e){
                console.log(e);
            }
            return v;
        }

        //job按钮
        let rightFirstDiv = document.getElementById("right").children[0];
        rightFirstDiv.addEventListener("click", function (evt){
            if(evt.target.tagName === "INPUT" && evt.target.type === "button"){
                if(evt.target.id === "createJob"){
                    let userId = document.getElementById("user").value;
                    if(userId.length > 0){
                        let id = BigInt(userId);
                        console.log("id:" + id);
                        createJob();
                    }
                }else if(evt.target.id === "delJob"){
                    delJob();
                }else if(evt.target.id === "calJob"){
                    callCMD();
                }else if(evt.target.id === "pauseJob"){
                    pause()
                }else if(evt.target.id === "getJob"){
                    listJob();
                }
                evt.stopImmediatePropagation();
                evt.stopPropagation();
            }
        });

        document.getElementById("clearOutput").onclick = function(){
            outPutDom.innerHTML = "";
        }

        //checkbox事件
        let allSelectDom = document.getElementById("allSelect");
        allSelectDom.addEventListener("click", function (evt){
            if(evt.target.tagName === "INPUT" && evt.target.type === "checkbox"){
                //console.log(evt.target.checked);
                if(evt.target.checked){
                    for (let i = 0; i < jobPanelDom.children.length; i++) {
                        let jobDom = jobPanelDom.children[i];
                        let input = jobDom.children[0].children[0];
                        input.checked = true;
                    }
                }else {
                    for (let i = 0; i < jobPanelDom.children.length; i++) {
                        let jobDom = jobPanelDom.children[i];
                        let input = jobDom.children[0].children[0];
                        input.checked = false;
                    }
                }
                evt.stopPropagation();
                evt.stopImmediatePropagation()
            }
        });

        let jobPanelDom = document.getElementById("jobPanel");
        jobPanelDom.addEventListener("click", function (evt){
            if(evt.target.tagName === "INPUT" && evt.target.type === "checkbox"){
                console.log(evt.target.checked);
            }
        });

        function findCode(code, codeMap){
            for (let i = 0; i < codeMap.length; i++) {
                let obj = codeMap[i];
                if(obj["code"] == code){
                    return obj;
                }
            }
            return null;
        }

        function createXHR(){
            let XHR = [
                function () { return new XMLHttpRequest() },
                function () { return new ActiveXObject("Msxml2.XMLHTTP")},
                function () { return new ActiveXObject("Msxml3.XMLHTTP")},
                function () { return new ActiveXObject("Microsoft.XMLHTTP")},
            ];
            let xhr = null;
            for(let i = 0; i < XHR.length; i++){
                try{
                    xhr = XHR[i]();
                }catch (e){
                    continue
                }
                break;
            }
            return xhr;
        }

        function sendGetRequest(url, data, contentType, callback){
            let xhr = createXHR();
            xhr.open("GET", url, true);
            if(contentType){
                xhr.setRequestHeader("Content-type", contentType);
                xhr.setRequestHeader("Accept", contentType+";charset=utf-8");
            } else {
                xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                xhr.setRequestHeader("Accept", "text/plain;charset=utf-8");
            }
            xhr.onreadystatechange = function (){
                if(xhr.readyState == 4){
                    if(xhr.status == 200 || xhr.status == 0){
                        callback(xhr.responseText)
                    }
                }
            }
            xhr.send(data);
        }

        function sendJOSONPostRequest(url, data, callback){
            sendPostRequest(url, data, "application/json", callback);
        }

        function sendPostRequest(url, data, contentType, callback){
            let xhr = createXHR();
            xhr.open("POST", url, true);
            if(contentType){
                xhr.setRequestHeader("Content-type", contentType);
            } else {
                xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            }
            xhr.onreadystatechange = function (){
                if(xhr.readyState == 4){
                    if(xhr.status == 200 || xhr.status == 0){
                        callback(xhr.responseText)
                    }
                }
            }
            xhr.send(data);
        }

        Date.prototype.format = function(fmt) {
            let o = {
                "M+" : this.getMonth()+1, //月份
                "d+" : this.getDate(), //日
                "h+" : this.getHours() % 12 == 0 ? 12 : this.getHours() % 12, //小时
                "H+" : this.getHours(), //小时
                "m+" : this.getMinutes(), //分
                "s+" : this.getSeconds(), //秒
                "q+" : Math.floor((this.getMonth()+3)/3), //季度
                "S" : this.getMilliseconds() //毫秒
            };
            let week = {
                "0" : "/u65e5",
                "1" : "/u4e00",
                "2" : "/u4e8c",
                "3" : "/u4e09",
                "4" : "/u56db",
                "5" : "/u4e94",
                "6" : "/u516d"
            };
            if(/(y+)/.test(fmt)){
                fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
            }
            if(/(E+)/.test(fmt)){
                fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "/u661f/u671f" : "/u5468") : "")+week[this.getDay()+""]);
            }
            for(let k in o){
                if(new RegExp("("+ k +")").test(fmt)){
                    fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
                }
            }
            return fmt;
        }

        listJob();
    })(window);
</script>
</html>